package org.lex.jdbc.url.persist;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.lex.jdbc.url.DriverConfig;
import org.lex.jdbc.url.JdbcUrlTemplate;
import org.lex.jdbc.url.persist.xml.XmlDaoHelper;

public abstract class AbstractJdbcTemplateDaoImpl extends XmlDaoHelper
		implements IJdbcTemplateDao {
	private static final String DEFAULT_TEMPLATES = "/org/lex/jdbc/default_drivers.xml";

	@Override
	public List<JdbcUrlTemplate> getSystemTemplates() throws IOException {
		InputStream in = null;
		List<JdbcUrlTemplate> results = new ArrayList<JdbcUrlTemplate>();
		try {
			in = AbstractJdbcTemplateDaoImpl.class
					.getResourceAsStream(DEFAULT_TEMPLATES);
			Document doc = new SAXReader().read(in);
			Element root = doc.getRootElement();
			for (Iterator<Element> driverElementIter = root
					.elementIterator("Driver"); driverElementIter.hasNext();) {
				Element driverElement = driverElementIter.next();
				String driverClassName = driverElement
						.elementTextTrim("driverClassName");
				String name = driverElement.elementTextTrim("name");
				String url = driverElement.elementTextTrim("url");
				String websiteUrl = driverElement.elementTextTrim("websiteUrl");

				DriverConfig dc = new DriverConfig().initialize(name,
						driverClassName, websiteUrl);

				JdbcUrlTemplate t = new JdbcUrlTemplate();
				t.setDescription("");
				t.setDriver(dc);
				t.setName(name);
				t.setTemplate(url);
			}
		} catch (DocumentException e) {
			throw new IOException("parse resource [" + DEFAULT_TEMPLATES
					+ "] failed, not a valid xml document", e);
		} finally {
			if (null != in) {
				in.close();
			}
		}
		return results;
	}

	@Override
	public boolean contains(String templateName) throws IOException {
		return null != this.getTemplateByName(templateName);
	}

	@Override
	public JdbcUrlTemplate getTemplateByName(String templateName)
			throws IOException {
		JdbcUrlTemplate results = this.getTemplateByName(
				this.getSystemTemplates(), templateName);
		if (null == results) {
			results = this.getTemplateByName(this.getUserTemplates(),
					templateName);
		}
		return results;
	}

	@Override
	public List<JdbcUrlTemplate> getTemplatesByDriver(String driverClass)
			throws IOException {
		List<JdbcUrlTemplate> results = this.getTemplatesByDriver(
				this.getSystemTemplates(), driverClass, null);
		this.getTemplatesByDriver(this.getUserTemplates(), driverClass, results);
		return results;
	}

	protected JdbcUrlTemplate getTemplateByName(
			Collection<JdbcUrlTemplate> templates, String templateName) {
		JdbcUrlTemplate results = null;
		for (JdbcUrlTemplate t : templates) {
			if (t.getName().equals(templateName)) {
				results = t;
				break;
			}
		}
		return results;
	}

	protected List<JdbcUrlTemplate> getTemplatesByDriver(
			Collection<JdbcUrlTemplate> templates, String driverClass,
			List<JdbcUrlTemplate> results) {
		if (null == results) {
			results = new ArrayList<JdbcUrlTemplate>();
		}
		for (JdbcUrlTemplate t : templates) {
			if (t.getDriver().getClassName().equals(driverClass)) {
				results.add(t);
			}
		}
		return results;
	}
}
